﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using GeoAPI.Geometries;

namespace NetTopologySuite.Geometries.Utilities
{
	public class LinearComponentExtracter : IGeometryComponentFilter
	{
		public static ICollection<IGeometry> GetLines(ICollection<IGeometry> geoms, ICollection<IGeometry> lines)
		{
			foreach (IGeometry geom in geoms)
			{
				LinearComponentExtracter.GetLines(geom, lines);
			}
			return lines;
		}

		public static ICollection<IGeometry> GetLines(ICollection<IGeometry> geoms, ICollection<IGeometry> lines, bool forceToLineString)
		{
			foreach (IGeometry geom in geoms)
			{
				LinearComponentExtracter.GetLines(geom, lines, forceToLineString);
			}
			return lines;
		}

		public static ICollection<IGeometry> GetLines(IGeometry geom, ICollection<IGeometry> lines)
		{
			if (geom is ILineString)
			{
				lines.Add(geom);
			}
			else
			{
				geom.Apply(new LinearComponentExtracter(lines));
			}
			return lines;
		}

		public static ICollection<IGeometry> GetLines(IGeometry geom, ICollection<IGeometry> lines, bool forceToLineString)
		{
			geom.Apply(new LinearComponentExtracter(lines, forceToLineString));
			return lines;
		}

		public static ICollection<IGeometry> GetLines(IGeometry geom)
		{
			Collection<IGeometry> collection = new Collection<IGeometry>();
			geom.Apply(new LinearComponentExtracter(collection));
			return collection;
		}

		public static ICollection<IGeometry> GetLines(IGeometry geom, bool forceToLineString)
		{
			Collection<IGeometry> collection = new Collection<IGeometry>();
			geom.Apply(new LinearComponentExtracter(collection, forceToLineString));
			return collection;
		}

		public static IGeometry GetGeometry(IGeometry geom)
		{
			ICollection<IGeometry> lines = LinearComponentExtracter.GetLines(geom);
			return geom.Factory.BuildGeometry(lines);
		}

		public static IGeometry GetGeometry(IGeometry geom, bool forceToLineString)
		{
			ICollection<IGeometry> lines = LinearComponentExtracter.GetLines(geom, forceToLineString);
			return geom.Factory.BuildGeometry(lines);
		}

		public LinearComponentExtracter(ICollection<IGeometry> lines) : this(lines, false)
		{
		}

		public LinearComponentExtracter(ICollection<IGeometry> lines, bool isForcedToLineString)
		{
			this._lines = lines;
			this.IsForcedToLineString = isForcedToLineString;
		}

		public bool IsForcedToLineString { get; set; }

		public void Filter(IGeometry geom)
		{
			if (this.IsForcedToLineString && geom is ILinearRing)
			{
				ILineString item = geom.Factory.CreateLineString(((ILinearRing)geom).CoordinateSequence);
				this._lines.Add(item);
				return;
			}
			if (geom is ILineString)
			{
				this._lines.Add(geom);
			}
		}

		private readonly ICollection<IGeometry> _lines;
	}
}
